/**
 * 运动员数据转换器
 * 用于前后端数据结构转换
 *
 * 设计原则:
 * 1. 后端返回的API数据 → 前端视图模型 (toViewModel)
 * 2. 前端表单数据 → 后端API数据 (toApiModel)
 * 3. 处理字段映射、类型转换、数据计算
 */

import { ManagementStatus, type AthleteInfo } from './types'
import type { AttachmentInfo } from '@/api/files/types'
import { useDict } from '@/composables/useDict'
import { SYSTEM_DICT, ATHLETE_DICT } from '@/constants/dictKeys'

// ============ 前端视图模型定义 ============

/**
 * 运动员视图模型 - 用于前端展示和编辑
 * 继承 AthleteInfo 并扩展前端专用字段
 */
export interface AthleteViewModel extends AthleteInfo {
	// ============ 前端视图模型 - 继承所有API字段，保持类型一致 ============

	// ============ 前端专用字段 (级联/范围选择器) ============
	trainOrgCascade?: [number, number] // 在训单位级联值 [1,100] 格式
	registerOrgCascade?: [number, number] // 注册单位级联值 [2,200] 格式
	agreementPeriod?: [string, string] // 协议周期 ['2024-01-01', '2024-12-31'] 数组格式

	// ============ 计算字段和显示字段 ============
	sexLabel?: string // 性别显示文本
	age?: number // 计算字段
	registerStatusLabel?: string // 注册状态显示文本

	// 需要通过字典转换成label的字段
	nationLabel?: string // 民族显示文本
	registerProjectLabel?: string // 注册项目显示文本
	trainOrgLabel?: string // 在训单位显示文本
	registerOrgLabel?: string // 注册单位显示文本

	auditStatusLabel?: string // 审核状态文本
	recheckStatusLabel?: string // 复审状态文本
	approvalStatusLabel?: string // 审批状态文本
	registerOrgName?: string // 注册单位名称(转换字段)
	registerProjectNames?: string[] // 注册项目名称列表(转换字段)
	trainOrgName?: string // 在训单位名称(转换字段)
	trainOrgTypeLabel?: string // 在训单位类型文本

	// ============ 文件信息字段 ============
	personPhotoFile?: AttachmentInfo // 个人照片文件信息
	identityFrontFile?: AttachmentInfo // 身份证正面文件信息 国徽面
	identityBackFile?: AttachmentInfo // 身份证反面文件信息  人像面
	qualificationsFile?: AttachmentInfo[] // 运动员资格证书文件信息列表
	otherMaterialFile?: AttachmentInfo[] // 其他证明材料文件信息列表
}

// ============ 辅助函数 ============

/**
 * 性别转换为文本
 */
function getSexLabel(sex?: number | string): string {
	if (sex === undefined || sex === null) return '未知'
	const map: Record<string, string> = {
		'0': '男',
		'1': '女'
	}
	return map[String(sex)] || '未知'
}

/**
 * 审核状态转换为文本
 */
function getAuditStatusLabel(status?: string | number): string {
	if (status === undefined || status === null) return '未知'
	const map: Record<string, string> = {
		'0': '待审核',
		'1': '无需审核',
		'2': '通过',
		'3': '不通过'
	}
	return map[String(status)] || '未知'
}

/**
 * 审批状态转换为文本
 */
function getApprovalStatusLabel(status?: string | number): string {
	if (status === undefined || status === null) return '未知'
	const map: Record<number, string> = {
		[ManagementStatus.PENDING]: '待处理',
		[ManagementStatus.APPROVED]: '已核准',
		[ManagementStatus.REJECTED]: '已驳回',
		[ManagementStatus.toRegister]: '待确认注册',
		[ManagementStatus.notSubmit]: '未提交'
	}
	return map[Number(status)] || '未知'
}

// ============ 核心转换器 ============

/**
 * API数据 → 前端视图模型
 * 用于: 详情页展示、列表展示、编辑表单初始化
 *
 * 注意: 此函数为同步函数，不会加载文件信息
 * 如需加载文件信息，请使用 toViewModelAsync
 */
export function toViewModel(api: AthleteInfo): AthleteViewModel {
	//  统一使用 useDict 获取所有字典查询方法
	const { getDictLabel, getRegisterOrgLabel, getTrainOrgLabel } = useDict([])

	return {
		...api, // 展开所有API字段，保持类型一致
		// 添加计算字段和显示字段
		sexLabel: getSexLabel(api.sex),

		// 字典与状态 label
		nationLabel: getDictLabel(SYSTEM_DICT.NATION, api.nation),
		registerProjectLabel: getDictLabel(ATHLETE_DICT.PROJECT, (api as any).registerProject),
		auditStatusLabel: getAuditStatusLabel(api.auditStatus),
		recheckStatusLabel: getAuditStatusLabel(api.recheckStatus),

		// 注册状态label
		approvalStatusLabel: getApprovalStatusLabel(api.approvalStatus),

		statusLabel: api.status === 0 ? '新增' : '确认',
		verifyFingerprintLabel: api.verifyFingerprint === 1 ? '新增' : '确认',

		// 变更
		changeTypeLabel: api.changeType === 1 ? '单位变更' : '项目变更',
		changeBeforeLabel:
			api.changeType === 1 ? getRegisterOrgLabel(api.changeBefore) : getDictLabel(ATHLETE_DICT.PROJECT, api.changeBefore),
		changeAfterLabel:
			api.changeType === 1 ? getRegisterOrgLabel(api.changeAfter) : getDictLabel(ATHLETE_DICT.PROJECT, api.changeAfter),

		// 组织级联 label
		trainOrgLabel: getTrainOrgLabel(api.trainOrgId),
		registerOrgLabel: getRegisterOrgLabel(api.registerOrgId),

		// 构建前端专用字段 (级联/范围选择器)
		trainOrgCascade: api.trainOrgType && api.trainOrgId ? [Number(api.trainOrgType), Number(api.trainOrgId)] : undefined,

		agreementPeriod: api.agreementStart && api.agreementEnd ? [api.agreementStart, api.agreementEnd] : undefined
	}
}

/**
 * API数据 → 前端视图模型 (异步版本)
 * 用于: 需要加载文件信息的场景
 * 会自动加载所有证件文件的详情
 */
export async function toViewModelAsync(api: AthleteInfo): Promise<AthleteViewModel> {
	const viewModel = toViewModel(api)

	//  加载所有文件信息
	const { getAttachmentById } = await import('@/api/files')

	// 定义需要加载的单个文件字段映射
	const singleFileFields = [
		{
			apiField: 'personPhoto',
			viewModelField: 'personPhotoFile' as const,
			label: '个人照片'
		},
		{
			apiField: 'identityFront',
			viewModelField: 'identityFrontFile' as const,
			label: '身份证正面'
		},
		{
			apiField: 'identityBack',
			viewModelField: 'identityBackFile' as const,
			label: '身份证反面'
		}
	]

	// 定义需要加载的数组文件字段映射
	const arrayFileFields = [
		{
			apiField: 'qualifications',
			viewModelField: 'qualificationsFile' as const,
			label: '运动员资格证书'
		},
		{
			apiField: 'otherMaterial',
			viewModelField: 'otherMaterialFile' as const,
			label: '其他证明材料'
		}
	]

	// 并发加载所有单个文件
	const singleFilePromises = singleFileFields.map(async ({ apiField, viewModelField, label }) => {
		const fileId = (api as any)[apiField]
		if (fileId) {
			try {
				const res = await getAttachmentById(fileId)
				if (res.code === 200 && res.data) {
					viewModel[viewModelField] = res.data
				}
			} catch (error) {
				console.error(`获取${label}文件信息失败:`, error)
			}
		}
	})

	// 并发加载所有数组文件
	const arrayFilePromises = arrayFileFields.map(async ({ apiField, viewModelField, label }) => {
		const fileIds = (api as any)[apiField] as number[] | undefined
		if (fileIds && Array.isArray(fileIds) && fileIds.length > 0) {
			try {
				// 并发加载所有文件ID
				const filePromises = fileIds.map(fileId => getAttachmentById(fileId))
				const responses = await Promise.all(filePromises)

				// 过滤成功的响应并提取数据
				const attachments = responses.filter(res => res.code === 200 && res.data).map(res => res.data)

				if (attachments.length > 0) {
					viewModel[viewModelField] = attachments
				}
			} catch (error) {
				console.error(`获取${label}文件信息失败:`, error)
			}
		}
	})

	// 等待所有文件加载完成
	await Promise.all([...singleFilePromises, ...arrayFilePromises])

	return viewModel
}

/**
 * 前端视图模型 → API数据
 * 用于: 新增、编辑提交
 */
export function toApiModel(viewModel: AthleteViewModel): AthleteInfo {
	// 过滤掉显示字段和前端专用字段
	const {
		// 显示字段
		sexLabel,
		age,
		registerStatusLabel,
		auditStatusLabel,
		recheckStatusLabel,
		approvalStatusLabel,
		registerOrgName,
		registerProjectNames,
		trainOrgName,
		trainOrgTypeLabel,
		// 前端专用字段 (级联/范围选择器)
		trainOrgCascade,
		agreementPeriod,
		...rest
	} = viewModel

	return {
		...rest,
		// 填充解析后的后端字段
		// 级联选择器返回的是 number 数组
		trainOrgType: Number(trainOrgCascade?.[0]),
		trainOrgId: Number(trainOrgCascade?.[1]),

		agreementStart: agreementPeriod?.[0],
		agreementEnd: agreementPeriod?.[1]
	} as AthleteInfo
}

// ============ 辅助转换函数 ============

/**
 * 批量转换: API数据数组 → 视图模型数组
 * 用于: 列表页
 * 注意: 同步版本，不会加载文件信息
 */
export function toViewModelList(apiList: AthleteInfo[]): AthleteViewModel[] {
	return apiList.map(toViewModel)
}

/**
 * 批量转换: API数据数组 → 视图模型数组 (异步版本)
 * 用于: 列表页，需要加载文件信息
 * 会并发加载所有运动员的照片文件信息
 */
export async function toViewModelListAsync(apiList: AthleteInfo[]): Promise<AthleteViewModel[]> {
	return Promise.all(apiList.map(toViewModelAsync))
}

// ============ 导出 ============
export default {
	toViewModel,
	toViewModelAsync,
	toApiModel,
	toViewModelList,
	toViewModelListAsync
}
